package com.yxsk.relay.job.component.endpoint.async;

import com.yxsk.relay.job.component.common.utils.CollectionUtils;
import com.yxsk.relay.job.component.endpoint.context.RelayJobNetContextHolder;
import com.yxsk.relay.job.component.endpoint.log.logger.RelayJobLoggerFactory;
import org.slf4j.Logger;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * @Author 11376
 * @CreaTime 2019/6/30 11:29
 * @Description slave端任务异步线程工作器
 */
public abstract class RelayJobAsyncWorker<V> implements Callable<V> {

    // 日志对象
    protected Logger logger = RelayJobLoggerFactory.getLogger(this.getClass());

    protected List<WorkInterceptor> interceptors;

    protected RelayJobAsyncWorker() {
        this.interceptors = Collections.synchronizedList(new LinkedList<>());
        // 注入上下文数据拦截器
        this.interceptors.add(new RelayJobNetContextHolder.AsyncTaskWorkInterceptor());
    }

    public void addInterceptors(List<WorkInterceptor> interceptors) {
        if (CollectionUtils.isNotEmpty(interceptors)) {
            this.interceptors.addAll(interceptors);
        }
    }

    protected abstract V work();

    @Override
    public final V call() throws Exception {
        return this.doWork();
    }

    private V doWork() {
        if (!CollectionUtils.isEmpty(this.interceptors)) {
            for (WorkInterceptor interceptor : this.interceptors) {
                interceptor.beforeWork();
            }
        }

        try {
            return this.work();
        } finally {
            if (!CollectionUtils.isEmpty(this.interceptors)) {
                for (WorkInterceptor interceptor : this.interceptors) {
                    interceptor.afterWork();
                }
            }
        }
    }


    public interface WorkInterceptor {

        void beforeWork();

        void afterWork();

    }

}
